﻿using System.Collections.Generic;
using System.Data.Objects.DataClasses;
using System.Linq;
using BusinessLibrary;
using MMSWebsite.HtmlHepler;
using MMSWebsite.Models;

namespace MMSWebsite.DataAccessManagement
{
    public class EmployeeAccessProvider
    {
        readonly MMSEntities _entities = new MMSEntities();

        public List<EmployeeViewModel> GetAllEmployee()
        {
            var employees = _entities.MMS_EMPLOYEEs.OrderBy(x=>x.EmpName);
            var list = new List<EmployeeViewModel>();
            foreach (var mmsEmployee in employees)
            {
                list.Add(ConvertEntitiesToModel(mmsEmployee));
            }

            return list;
        }

        public EmployeeViewModel GetEmployeeById(int? id)
        {
            var employee = _entities.MMS_EMPLOYEEs.FirstOrDefault(e => e.Id == id);

            return ConvertEntitiesToModel(employee);
        }

        public EmployeeViewModel GetEmployeeByCode(string code)
        {
            var employee = _entities.MMS_EMPLOYEEs.FirstOrDefault(e => e.EmpCode == code);

            return ConvertEntitiesToModel(employee);
        }

        public EmployeeViewModel GetEmployeeByName(string name)
        {
            var employee = _entities.MMS_EMPLOYEEs.FirstOrDefault(e => e.EmpName == name);

            return ConvertEntitiesToModel(employee);
        }

        public void AddEmployee(EmployeeViewModel empModel)
        {
            //add information Employee
            var newEmp = new MMS_EMPLOYEE
                             {
                                 EmpCode = empModel.Employee.Code,
                                 Password = empModel.Employee.Password,
                                 Birth = empModel.Employee.Birth,
                                 EmpEmail = empModel.Employee.Email,
                                 EmpName = empModel.Employee.Name,
                                 Phone = empModel.Employee.Phone,
                                 Sex = empModel.Employee.Sex,
                                 IdCode = empModel.Employee.IdCode, 
                                 IsLocked = empModel.Employee.IsLocked,
                                 NumberAddress = empModel.Employee.NumberAddress
                                 
                             };

            //add address to database
            var area =
                    _entities.MMS_AREAs.FirstOrDefault(
                        x => x.CityName == empModel.Employee.Area.CityName && x.DistrictName == empModel.Employee.Area.DistrictName);
            newEmp.MMS_AREA = area;

            //add role
            foreach (var role in empModel.Roles)
            {
                if (!role.RoleIsChecked) continue;
                var newrole = _entities.MMS_ROLEs.Single(r => r.RoleName == role.Role.RoleName);
                    
                newEmp.MMS_ROLE.Add(newrole);
            }

            _entities.AddToMMS_EMPLOYEEs(newEmp);
            _entities.SaveChanges();
        }

        public void UpdateEmployee(EmployeeViewModel employee)
        {
            var emp = _entities.MMS_EMPLOYEEs.Single(e => e.Id == employee.Employee.Id);
            //update base information
            emp.EmpCode = employee.Employee.Code;
            emp.EmpName = employee.Employee.Name;
            emp.Password = employee.Employee.Password;
            emp.IdCode = employee.Employee.IdCode;
            emp.EmpEmail = employee.Employee.Email;
            emp.Phone = employee.Employee.Phone;
            emp.Sex = employee.Employee.Sex;
            emp.Birth = employee.Employee.Birth;
            emp.NumberAddress = employee.Employee.NumberAddress;

            //update address
            //emp.MMS_ADDRESS = employee.Employee.Address;
            var area =
                    _entities.MMS_AREAs.FirstOrDefault(
                        x => x.CityName == employee.Employee.Area.CityName && x.DistrictName == employee.Employee.Area.DistrictName);
            emp.MMS_AREA = area;

            //first - delete all roles 
            var deleteRoles = emp.MMS_ROLE;
            foreach (var deleteRole in deleteRoles.ToArray())
            {
                emp.MMS_ROLE.Remove(deleteRole);
            }

            //Add again
            //add role
            foreach (var role in employee.Roles)
            {
                if (!role.RoleIsChecked) continue;
                var newrole = _entities.MMS_ROLEs.Single(r => r.RoleName == role.Role.RoleName);

                emp.MMS_ROLE.Add(newrole);
            }

            _entities.SaveChanges();


        }

        private EmployeeViewModel ConvertEntitiesToModel(MMS_EMPLOYEE employee )
        {
            if (employee == null) return null;
            var emp = new EmployeeViewModel
                          {
                              Employee = new Employee
                                             {
                                                 Code = employee.EmpCode,
                                                 Password = employee.Password,
                                                 Id = employee.Id,
                                                 Name = employee.EmpName,
                                                 IdCode = employee.IdCode,
                                                 Email = employee.EmpEmail,
                                                 Phone = employee.Phone,
                                                 Sex = employee.Sex,
                                                 Birth = employee.Birth,
                                                 NumberAddress = employee.NumberAddress,
                                                 Area = employee.MMS_AREA,
                                                 IsLocked = employee.IsLocked
                                             }
                          };

            var userInRoles = employee.MMS_ROLE;

            foreach (var role in emp.Roles)
            {
                foreach (var userInRole in userInRoles)
                {
                    if (userInRole.RoleName == role.Role.RoleName)
                        role.RoleIsChecked = true;
                }
            }

            return emp;
        }

        public void TriggerLock(int id)
        {
            var employee = _entities.MMS_EMPLOYEEs.FirstOrDefault(x => x.Id == id);
            employee.IsLocked = employee.IsLocked != true;
            _entities.SaveChanges();
        }

        public List<EmployeeViewModel> GetEmpsByRole(string rolename)
        {
            var emps = GetAllEmployee();
            return emps.Where(x => x.Roles.Any(r => r.RoleIsChecked == true && r.Role.RoleName == rolename)).ToList();
        }

        public List<string> GetRolesOfEmp(EmployeeViewModel emp)
        {
            var roles = new List<string>();
            if (emp == null)
            {
                return null;
            }
            else
            {
                foreach (var role in emp.Roles)
                {
                    if(role.RoleIsChecked == true) roles.Add(role.Role.RoleName);
                }
            }
            return roles;

        }

        public void ResetPassword(int empId)
        {
            var emp = _entities.MMS_EMPLOYEEs.FirstOrDefault(x => x.Id == empId);
            string randompass = CodeGenerator.AutoGeneratePass(5);
            WebMailHelper.SendPassword(emp.EmpEmail, emp.EmpName, emp.EmpCode, randompass);
            //enscrypt and save db
            emp.Password = MD5Security.GetMd5Hash(randompass);
            _entities.SaveChanges();
        }
    }
}